home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / SampleList.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  26.5 KB  |  921 lines  |  [TEXT/KAHL]

  1. /* SampleList.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "SampleList.h"
  31. #include "Memory.h"
  32. #include "StringList.h"
  33. #include "Array.h"
  34. #include "SampleObject.h"
  35. #include "Alert.h"
  36. #include "DataMunging.h"
  37. #include "PcodeSystem.h"
  38. #include "BufferedFileInput.h"
  39. #include "BufferedFileOutput.h"
  40. #include "Files.h"
  41. #include "Scrap.h"
  42.  
  43.  
  44. struct SampleListRec
  45.     {
  46.         StringListRec*                    List;
  47.         struct CodeCenterRec*        CodeCenter;
  48.         struct MainWindowRec*        MainWindow;
  49.         ArrayRec*                                SampleArray;
  50.         MyBoolean                                SampleListChanged;
  51.     };
  52.  
  53.  
  54. #define MAGICSCRAPSTRING ("\xff\x00\x1f\xfe SampleObjectScrap")
  55.  
  56.  
  57. SampleListRec*            NewSampleList(struct MainWindowRec* MainWindow,
  58.                                             struct CodeCenterRec* CodeCenter, WinType* ScreenID,
  59.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  60.     {
  61.         SampleListRec*        SampList;
  62.  
  63.         SampList = (SampleListRec*)AllocPtrCanFail(sizeof(SampleListRec),"SampleListRec");
  64.         if (SampList == NIL)
  65.             {
  66.              FailurePoint1:
  67.                 return NIL;
  68.             }
  69.         SampList->List = NewStringList(ScreenID,XLoc,YLoc,Width,Height,
  70.             GetScreenFont(),9,StringListDontAllowMultipleSelection,"Samples");
  71.         if (SampList->List == NIL)
  72.             {
  73.              FailurePoint2:
  74.                 ReleasePtr((char*)SampList);
  75.                 goto FailurePoint1;
  76.             }
  77.         SampList->SampleArray = NewArray();
  78.         if (SampList->SampleArray == NIL)
  79.             {
  80.              FailurePoint3:
  81.                 DisposeStringList(SampList->List);
  82.                 goto FailurePoint2;
  83.             }
  84.         SampList->CodeCenter = CodeCenter;
  85.         SampList->MainWindow = MainWindow;
  86.         SampList->SampleListChanged = False;
  87.         return SampList;
  88.     }
  89.  
  90.  
  91. /* delete the sample list and all of the samples it contains */
  92. void                                DisposeSampleList(SampleListRec* SampList)
  93.     {
  94.         long                            Scan;
  95.         long                            Limit;
  96.  
  97.         CheckPtrExistence(SampList);
  98.         Limit = ArrayGetLength(SampList->SampleArray);
  99.         for (Scan = 0; Scan < Limit; Scan += 1)
  100.             {
  101.                 SampleObjectRec*    SampleTemp;
  102.  
  103.                 SampleTemp = (SampleObjectRec*)ArrayGetElement(SampList->SampleArray,Scan);
  104.                 DisposeSampleObject(SampleTemp);
  105.             }
  106.         DisposeArray(SampList->SampleArray);
  107.         DisposeStringList(SampList->List);
  108.         ReleasePtr((char*)SampList);
  109.     }
  110.  
  111.  
  112. /* change the location of the sample list in the window */
  113. void                                SetSampleListLocation(SampleListRec* SampList,
  114.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  115.     {
  116.         CheckPtrExistence(SampList);
  117.         SetStringListLoc(SampList->List,XLoc,YLoc,Width,Height);
  118.     }
  119.  
  120.  
  121. /* redraw the list */
  122. void                                SampleListRedraw(SampleListRec* SampList)
  123.     {
  124.         CheckPtrExistence(SampList);
  125.         RedrawStringList(SampList->List);
  126.     }
  127.  
  128.  
  129. /* see if the specified coordinates falls inside the sample list rectangle */
  130. MyBoolean                        SampleListHitTest(SampleListRec* SampList,
  131.                                             OrdType XLoc, OrdType YLoc)
  132.     {
  133.         CheckPtrExistence(SampList);
  134.         return StringListHitTest(SampList->List,XLoc,YLoc);
  135.     }
  136.  
  137.  
  138. /* handle a mouse down event for the sample list */
  139. void                                SampleListDoMouseDown(SampleListRec* SampList, OrdType XLoc,
  140.                                             OrdType YLoc, ModifierFlags Modifiers)
  141.     {
  142.         CheckPtrExistence(SampList);
  143.         if (StringListMouseDown(SampList->List,XLoc,YLoc,Modifiers))
  144.             {
  145.                 /* if it returns true, then it was a double click */
  146.                 SampleListOpenSelection(SampList);
  147.             }
  148.     }
  149.  
  150.  
  151. /* called when the window becomes active */
  152. void                                SampleListBecomeActive(SampleListRec* SampList)
  153.     {
  154.         CheckPtrExistence(SampList);
  155.         EnableStringList(SampList->List);
  156.     }
  157.  
  158.  
  159. /* called when the window becomes inactive */
  160. void                                SampleListBecomeInactive(SampleListRec* SampList)
  161.     {
  162.         CheckPtrExistence(SampList);
  163.         DisableStringList(SampList->List);
  164.     }
  165.  
  166.  
  167. /* called when a selection is made in another list, so that this list */
  168. /* is deselected */
  169. void                                SampleListDeselect(SampleListRec* SampList)
  170.     {
  171.         CheckPtrExistence(SampList);
  172.         DeselectAllStringListElements(SampList->List);
  173.     }
  174.  
  175.  
  176. /* check to see if there is a selection in this list */
  177. MyBoolean                        SampleListIsThereSelection(SampleListRec* SampList)
  178.     {
  179.         CheckPtrExistence(SampList);
  180.         return (GetStringListHowManySelectedItems(SampList->List) > 0);
  181.     }
  182.  
  183.  
  184. /* check to see if any of the samples contained in this list need to be saved */
  185. MyBoolean                        DoesSampleListNeedToBeSaved(SampleListRec* SampList)
  186.     {
  187.         long                            Scan;
  188.         long                            Limit;
  189.         MyBoolean                    Flag;
  190.  
  191.         CheckPtrExistence(SampList);
  192.         Flag = SampList->SampleListChanged;
  193.         Limit = ArrayGetLength(SampList->SampleArray);
  194.         for (Scan = 0; (Scan < Limit) && !Flag; Scan += 1)
  195.             {
  196.                 SampleObjectRec*    SampleTemp;
  197.  
  198.                 SampleTemp = (SampleObjectRec*)ArrayGetElement(SampList->SampleArray,Scan);
  199.                 if (HasSampleObjectBeenModified(SampleTemp))
  200.                     {
  201.                         Flag = True;
  202.                     }
  203.             }
  204.         return Flag;
  205.     }
  206.  
  207.  
  208. /* open an edit window for the selected sample */
  209. void                                SampleListOpenSelection(SampleListRec* SampList)
  210.     {
  211.         ArrayRec*                    ListOfSelections;
  212.  
  213.         CheckPtrExistence(SampList);
  214.         ListOfSelections = GetListOfSelectedItems(SampList->List);
  215.         if (ListOfSelections != NIL)
  216.             {
  217.                 long                            Scan;
  218.                 long                            Limit;
  219.  
  220.                 Limit = ArrayGetLength(ListOfSelections);
  221.                 for (Scan = 0; Scan < Limit; Scan += 1)
  222.                     {
  223.                         SampleObjectRec*        SampleTemp;
  224.  
  225.                         SampleTemp = (SampleObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  226.                         SampleObjectOpenWindow(SampleTemp);
  227.                     }
  228.                 DisposeArray(ListOfSelections);
  229.             }
  230.     }
  231.  
  232.  
  233. /* create a new sample and open a window for it */
  234. void                                SampleListNewSample(SampleListRec* SampList)
  235.     {
  236.         SampleObjectRec*    Sample;
  237.  
  238.         CheckPtrExistence(SampList);
  239.         /* create the object */
  240.         Sample = NewSampleObject(SampList->CodeCenter,SampList->MainWindow,SampList);
  241.         if (Sample == NIL)
  242.             {
  243.              FailurePoint1:
  244.                 AlertHalt("There is not enough memory available to create a new sample.",NIL);
  245.                 return;
  246.             }
  247.         /* add it to the string list */
  248.         if (!InsertStringListElement(SampList->List,NIL,NIL,Sample,True))
  249.             {
  250.              FailurePoint2:
  251.                 DisposeSampleObject(Sample);
  252.                 goto FailurePoint1;
  253.             }
  254.         MainWindowDeselectAllOtherStringLists(SampList->MainWindow,SampList);
  255.         SelectStringListElement(SampList->List,Sample);
  256.         MakeStringListSelectionVisible(SampList->List);
  257.         /* add it to the array */
  258.         if (!ArrayAppendElement(SampList->SampleArray,Sample))
  259.             {
  260.              FailurePoint3:
  261.                 RemoveStringListElement(SampList->List,Sample,True);
  262.                 goto FailurePoint2;
  263.             }
  264.         /* update our internal flags */
  265.         SampList->SampleListChanged = True;
  266.         /* change the name in the list */
  267.         SampleListSampleNameChanged(SampList,Sample);
  268.         /* show the window */
  269.         SampleObjectOpenWindow(Sample);
  270.     }
  271.  
  272.  
  273. /* delete the selected sample */
  274. void                                SampleListDeleteSelection(SampleListRec* SampList)
  275.     {
  276.         ArrayRec*                    ListOfSelections;
  277.  
  278.         CheckPtrExistence(SampList);
  279.         ListOfSelections = GetListOfSelectedItems(SampList->List);
  280.         if (ListOfSelections != NIL)
  281.             {
  282.                 long                                Scan;
  283.                 long                                Limit;
  284.  
  285.                 Limit = ArrayGetLength(ListOfSelections);
  286.                 for (Scan = 0; Scan < Limit; Scan += 1)
  287.                     {
  288.                         SampleObjectRec*    OneToZap;
  289.  
  290.                         OneToZap = (SampleObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  291.                         SampleListDeleteSample(SampList,OneToZap);
  292.                     }
  293.                 DisposeArray(ListOfSelections);
  294.             }
  295.     }
  296.  
  297.  
  298. /* delete the explicitly specified sample */
  299. void                                SampleListDeleteSample(SampleListRec* SampList,
  300.                                             struct SampleObjectRec* TheSample)
  301.     {
  302.         long                                Scan;
  303.         long                                Limit;
  304.  
  305.         CheckPtrExistence(SampList);
  306.         Limit = ArrayGetLength(SampList->SampleArray);
  307.         for (Scan = 0; Scan < Limit; Scan += 1)
  308.             {
  309.                 SampleObjectRec*        SampleTemp;
  310.  
  311.                 SampleTemp = (SampleObjectRec*)ArrayGetElement(SampList->SampleArray,Scan);
  312.  
  313.                 if (TheSample == SampleTemp)
  314.                     {
  315.                         FileSpec*                    BackupFileWhere;
  316.                         FileType*                    BackupFile;
  317.                         MyBoolean                    Success = False;
  318.  
  319.                         BackupFileWhere = NewTempFileSpec(CODE4BYTES('?','?','?','?'),
  320.                             CODE4BYTES('?','?','?','?'));
  321.                         if (BackupFileWhere != NIL)
  322.                             {
  323.                                 if (OpenFile(BackupFileWhere,&BackupFile,eReadAndWrite))
  324.                                     {
  325.                                         BufferedOutputRec*    Output;
  326.  
  327.                                         Output = NewBufferedOutput(BackupFile);
  328.                                         if (Output != NIL)
  329.                                             {
  330.                                                 if (WriteBufferedOutput(Output,sizeof(MAGICSCRAPSTRING),
  331.                                                     MAGICSCRAPSTRING))
  332.                                                     {
  333.                                                         if (SampleObjectWriteOutData(TheSample,Output)
  334.                                                             == eFileLoadNoError)
  335.                                                             {
  336.                                                                 Success = True;
  337.                                                             }
  338.                                                     }
  339.                                                 if (!EndBufferedOutput(Output))
  340.                                                     {
  341.                                                         Success = False;
  342.                                                     }
  343.                                             }
  344.                                          else
  345.                                             {
  346.                                                 CloseFile(BackupFile);
  347.                                             }
  348.                                     }
  349.                                  else
  350.                                     {
  351.                                         DeleteFile(BackupFileWhere);
  352.                                         DisposeFileSpec(BackupFileWhere);
  353.                                     }
  354.                             }
  355.                         if (Success)
  356.                             {
  357.                                 MainWindowNewDeleteUndoInfo(SampList->MainWindow,BackupFileWhere,
  358.                                     BackupFile);
  359.                                 DisposeSampleObject(SampleTemp);
  360.                                 RemoveStringListElement(SampList->List,SampleTemp,True);
  361.                                 ArrayDeleteElement(SampList->SampleArray,Scan);
  362.                                 SampList->SampleListChanged = True;
  363.                             }
  364.                          else
  365.                             {
  366.                                 YesNoCancelType        Decision;
  367.  
  368.                                 Decision = AskYesNoCancel("Unable to save undo information for object.  "
  369.                                     "Delete object anyway?",NIL,"Delete","Cancel",NIL/*nothirdbutton*/);
  370.                                 if (Decision == eYes)
  371.                                     {
  372.                                         DisposeSampleObject(SampleTemp);
  373.                                         RemoveStringListElement(SampList->List,SampleTemp,True);
  374.                                         ArrayDeleteElement(SampList->SampleArray,Scan);
  375.                                         SampList->SampleListChanged = True;
  376.                                     }
  377.                             }
  378.                         return;
  379.                     }
  380.             }
  381.         EXECUTE(PRERR(AllowResume,"SampleListDeleteSample:  couldn't find object"));
  382.     }
  383.  
  384.  
  385. /* the name of a sample has changed, so the name in the scrolling */
  386. /* list must also be changed */
  387. void                                SampleListSampleNameChanged(SampleListRec* SampList,
  388.                                             struct SampleObjectRec* TheSample)
  389.     {
  390.         char*                            SampleName;
  391.  
  392.         CheckPtrExistence(SampList);
  393.         CheckPtrExistence(TheSample);
  394.         ERROR(ArrayFindElement(SampList->SampleArray,TheSample) < 0,
  395.             PRERR(ForceAbort,"SampleListSampleNameChanged:  unknown sample"));
  396.         SampleName = SampleObjectGetNameCopy(TheSample);
  397.         if (SampleName != NIL)
  398.             {
  399.                 char*                            SampleNameNullTerminated;
  400.  
  401.                 SampleNameNullTerminated = BlockToStringCopy(SampleName);
  402.                 if (SampleNameNullTerminated != NIL)
  403.                     {
  404.                         ChangeStringListElementName(SampList->List,
  405.                             SampleNameNullTerminated,TheSample);
  406.                         ReleasePtr(SampleNameNullTerminated);
  407.                     }
  408.                 ReleasePtr(SampleName);
  409.             }
  410.     }
  411.  
  412.  
  413. /* look for a specified sample.  returns NIL if not found.  the name is NOT null */
  414. /* terminated */
  415. SampleObjectRec*        SampleListLookupNamedSample(SampleListRec* SampList, char* Name)
  416.     {
  417.         long                            Scan;
  418.         long                            Limit;
  419.  
  420.         CheckPtrExistence(SampList);
  421.         CheckPtrExistence(Name);
  422.         Limit = ArrayGetLength(SampList->SampleArray);
  423.         for (Scan = 0; Scan < Limit; Scan += 1)
  424.             {
  425.                 SampleObjectRec*        Sample;
  426.                 char*                                NameCopy;
  427.  
  428.                 Sample = (SampleObjectRec*)ArrayGetElement(SampList->SampleArray,Scan);
  429.                 NameCopy = SampleObjectGetNameCopy(Sample);
  430.                 if (NameCopy != NIL)
  431.                     {
  432.                         if (PtrSize(Name) == PtrSize(NameCopy))
  433.                             {
  434.                                 if (MemEqu(Name,NameCopy,PtrSize(Name)))
  435.                                     {
  436.                                         ReleasePtr(NameCopy);
  437.                                         return Sample;
  438.                                     }
  439.                             }
  440.                         ReleasePtr(NameCopy);
  441.                     }
  442.             }
  443.         return NIL;
  444.     }
  445.  
  446.  
  447. SampleErrors                SampleListGetSampleLeftFixed(SampleListRec* SampList,
  448.                                             char* Name, largefixedsigned** DataOut)
  449.     {
  450.         SampleObjectRec*        Sample;
  451.  
  452.         CheckPtrExistence(SampList);
  453.         ERROR(DataOut == NIL,PRERR(ForceAbort,
  454.             "SampleListGetSampleLeftFixed:  data out is NIL"));
  455.         Sample = SampleListLookupNamedSample(SampList,Name);
  456.         if (Sample == NIL)
  457.             {
  458.                 return eEvalSampleUndefined;
  459.             }
  460.         if (eSampleStereo != SampleObjectGetNumChannels(Sample))
  461.             {
  462.                 return eEvalSampleWrongChannel;
  463.             }
  464.         *DataOut = SampleObjectGetLeftFixed(Sample);
  465.         if (*DataOut == NIL)
  466.             {
  467.                 return eEvalSampleNotEnoughMemoryToCopy;
  468.             }
  469.         return eEvalSampleNoError;
  470.     }
  471.  
  472.  
  473. SampleErrors                SampleListGetSampleRightFixed(SampleListRec* SampList,
  474.                                             char* Name, largefixedsigned** DataOut)
  475.     {
  476.         SampleObjectRec*        Sample;
  477.  
  478.         CheckPtrExistence(SampList);
  479.         ERROR(DataOut == NIL,PRERR(ForceAbort,
  480.             "SampleListGetSampleRightFixed:  data out is NIL"));
  481.         Sample = SampleListLookupNamedSample(SampList,Name);
  482.         if (Sample == NIL)
  483.             {
  484.                 return eEvalSampleUndefined;
  485.             }
  486.         if (eSampleStereo != SampleObjectGetNumChannels(Sample))
  487.             {
  488.                 return eEvalSampleWrongChannel;
  489.             }
  490.         *DataOut = SampleObjectGetRightFixed(Sample);
  491.         if (*DataOut == NIL)
  492.             {
  493.                 return eEvalSampleNotEnoughMemoryToCopy;
  494.             }
  495.         return eEvalSampleNoError;
  496.     }
  497.  
  498.  
  499. SampleErrors                SampleListGetSampleMonoFixed(SampleListRec* SampList,
  500.                                             char* Name, largefixedsigned** DataOut)
  501.     {
  502.         SampleObjectRec*        Sample;
  503.  
  504.         CheckPtrExistence(SampList);
  505.         ERROR(DataOut == NIL,PRERR(ForceAbort,
  506.             "SampleListGetSampleMonoFixed:  data out is NIL"));
  507.         Sample = SampleListLookupNamedSample(SampList,Name);
  508.         if (Sample == NIL)
  509.             {
  510.                 return eEvalSampleUndefined;
  511.             }
  512.         if (eSampleMono != SampleObjectGetNumChannels(Sample))
  513.             {
  514.                 return eEvalSampleWrongChannel;
  515.             }
  516.         *DataOut = SampleObjectGetMonoFixed(Sample);
  517.         if (*DataOut == NIL)
  518.             {
  519.                 return eEvalSampleNotEnoughMemoryToCopy;
  520.             }
  521.         return eEvalSampleNoError;
  522.     }
  523.  
  524.  
  525. /* use the provided data to open a new sample with the specified attributes. */
  526. /* this is used when opening an algorithmic sample as a data sample. */
  527. /* RawData MUST be valid. */
  528. SampleObjectRec*        SampleListCopyRawSampleAndOpen(SampleListRec* SampList,
  529.                                             char* RawData, NumBitsType NumBits, NumChannelsType NumChannels,
  530.                                             long Origin, long LoopStart1, long LoopStart2, long LoopStart3,
  531.                                             long LoopEnd1, long LoopEnd2, long LoopEnd3, long SamplingRate,
  532.                                             double NaturalFrequency)
  533.     {
  534.         SampleObjectRec*    Sample;
  535.  
  536.         CheckPtrExistence(SampList);
  537.         CheckPtrExistence(RawData);
  538.         /* create the object */
  539.         Sample = NewSampleObjectInitialized(SampList->CodeCenter,SampList->MainWindow,
  540.             SampList,RawData,NumBits,NumChannels,Origin,LoopStart1,LoopStart2,LoopStart3,
  541.             LoopEnd1,LoopEnd2,LoopEnd3,SamplingRate,NaturalFrequency);
  542.         if (Sample == NIL)
  543.             {
  544.              FailurePoint1:
  545.                 AlertHalt("There is not enough memory available to create a new sample.",NIL);
  546.                 return NIL;
  547.             }
  548.         /* add it to the string list */
  549.         if (!InsertStringListElement(SampList->List,NIL,NIL,Sample,True))
  550.             {
  551.              FailurePoint2:
  552.                 DisposeSampleObject(Sample);
  553.                 goto FailurePoint1;
  554.             }
  555.         MainWindowDeselectAllOtherStringLists(SampList->MainWindow,SampList);
  556.         SelectStringListElement(SampList->List,Sample);
  557.         MakeStringListSelectionVisible(SampList->List);
  558.         /* add it to the array */
  559.         if (!ArrayAppendElement(SampList->SampleArray,Sample))
  560.             {
  561.              FailurePoint3:
  562.                 RemoveStringListElement(SampList->List,Sample,True);
  563.                 goto FailurePoint2;
  564.             }
  565.         /* update our internal flags */
  566.         SampList->SampleListChanged = True;
  567.         /* change the name in the list */
  568.         SampleListSampleNameChanged(SampList,Sample);
  569.         /* show the window */
  570.         SampleObjectOpenWindow(Sample);
  571.         return Sample;
  572.     }
  573.  
  574.  
  575. /* the document's name has changed, so the windows have to be updated */
  576. void                                SampleListGlobalNameChange(SampleListRec* SampleList,
  577.                                             char* NewFilename)
  578.     {
  579.         long                            Scan;
  580.         long                            Limit;
  581.  
  582.         CheckPtrExistence(SampleList);
  583.         Limit = ArrayGetLength(SampleList->SampleArray);
  584.         for (Scan = 0; Scan < Limit; Scan += 1)
  585.             {
  586.                 SampleObjectRec*        Sample;
  587.  
  588.                 Sample = (SampleObjectRec*)ArrayGetElement(SampleList->SampleArray,Scan);
  589.                 SampleObjectGlobalNameChange(Sample,NewFilename);
  590.             }
  591.     }
  592.  
  593.  
  594. /*   4-bytes little endian number of sample objects (positive 2s complement) */
  595. /*   n-bytes of data for the sampe objects */
  596.  
  597.  
  598. /* read sample objects from a file.  returns True if fully successful. */
  599. FileLoadingErrors        SampleListReadData(SampleListRec* SampleList,
  600.                                             struct BufferedInputRec* Input)
  601.     {
  602.         signed long                NumSampleObjects;
  603.         long                            Scan;
  604.  
  605.         CheckPtrExistence(SampleList);
  606.         CheckPtrExistence(Input);
  607.  
  608.         /*   4-bytes little endian number of sample objects */
  609.         if (!ReadBufferedSignedLongLittleEndian(Input,&NumSampleObjects))
  610.             {
  611.                 return eFileLoadDiskError;
  612.             }
  613.         if (NumSampleObjects < 0)
  614.             {
  615.                 return eFileLoadBadFormat;
  616.             }
  617.  
  618.         /* load the objects */
  619.         for (Scan = 0; Scan < NumSampleObjects; Scan += 1)
  620.             {
  621.                 SampleObjectRec*    Sample EXECUTE(= (SampleObjectRec*)0x81818181);
  622.                 FileLoadingErrors    Error;
  623.  
  624.                 /* read the sample object from the file */
  625.                 Error = SampleObjectNewFromFile(&Sample,Input,SampleList->CodeCenter,
  626.                     SampleList->MainWindow,SampleList);
  627.                 if (Error != eFileLoadNoError)
  628.                     {
  629.                      FailurePoint1:
  630.                         return Error;
  631.                     }
  632.                 CheckPtrExistence(Sample);
  633.                 /* add it to the string list */
  634.                 if (!InsertStringListElement(SampleList->List,NIL,NIL,Sample,True))
  635.                     {
  636.                      FailurePoint2:
  637.                         DisposeSampleObject(Sample);
  638.                         Error = eFileLoadOutOfMemory;
  639.                         goto FailurePoint1;
  640.                     }
  641.                 /* add it to the array */
  642.                 if (!ArrayAppendElement(SampleList->SampleArray,Sample))
  643.                     {
  644.                      FailurePoint3:
  645.                         RemoveStringListElement(SampleList->List,Sample,True);
  646.                         goto FailurePoint2;
  647.                     }
  648.                 /* change the name in the list */
  649.                 SampleListSampleNameChanged(SampleList,Sample);
  650.             }
  651.  
  652.         return eFileLoadNoError;
  653.     }
  654.  
  655.  
  656. /* write sample objects to a file.  returns True if fully successful. */
  657. FileLoadingErrors        SampleListWriteData(SampleListRec* SampleList,
  658.                                             struct BufferedOutputRec* Output)
  659.     {
  660.         signed long                NumSampleObjects;
  661.         long                            Scan;
  662.  
  663.         CheckPtrExistence(SampleList);
  664.         CheckPtrExistence(Output);
  665.  
  666.         /*   4-bytes little endian number of sample objects (positive 2s complement) */
  667.         NumSampleObjects = ArrayGetLength(SampleList->SampleArray);
  668.         if (!WriteBufferedSignedLongLittleEndian(Output,NumSampleObjects))
  669.             {
  670.                 return eFileLoadDiskError;
  671.             }
  672.  
  673.         /* write out the samples */
  674.         for (Scan = 0; Scan < NumSampleObjects; Scan += 1)
  675.             {
  676.                 SampleObjectRec*        Sample;
  677.                 FileLoadingErrors        Error;
  678.  
  679.                 /* get the sample */
  680.                 Sample = (SampleObjectRec*)ArrayGetElement(SampleList->SampleArray,Scan);
  681.                 /* write it out */
  682.                 Error = SampleObjectWriteOutData(Sample,Output);
  683.                 /* handle mishaps */
  684.                 if (Error != eFileLoadNoError)
  685.                     {
  686.                         return Error;
  687.                     }
  688.             }
  689.  
  690.         return eFileLoadNoError;
  691.     }
  692.  
  693.  
  694. /* after a file has been saved, this is called to mark all objects as not modified. */
  695. void                                SampleListMarkAllObjectsSaved(SampleListRec* SampleList)
  696.     {
  697.         long                            Scan;
  698.         long                            Limit;
  699.  
  700.         CheckPtrExistence(SampleList);
  701.         Limit = ArrayGetLength(SampleList->SampleArray);
  702.         for (Scan = 0; Scan < Limit; Scan += 1)
  703.             {
  704.                 SampleObjectRec*        Sample;
  705.  
  706.                 Sample = (SampleObjectRec*)ArrayGetElement(SampleList->SampleArray,Scan);
  707.                 SampleObjectMarkAsSaved(Sample);
  708.             }
  709.         SampleList->SampleListChanged = False;
  710.     }
  711.  
  712.  
  713. /* copy the selected object in the list to the clipboard.  return False if failed. */
  714. MyBoolean                        SampleListCopyObject(SampleListRec* SampleList)
  715.     {
  716.         ArrayRec*                            ListOfSelections;
  717.         MyBoolean                            TotalSuccessFlag = False;
  718.  
  719.         CheckPtrExistence(SampleList);
  720.         ListOfSelections = GetListOfSelectedItems(SampleList->List);
  721.         if (ListOfSelections != NIL)
  722.             {
  723.                 if (ArrayGetLength(ListOfSelections) >= 1)
  724.                     {
  725.                         SampleObjectRec*        SampleTemp;
  726.                         FileSpec*                        TempFileLocation;
  727.  
  728.                         SampleTemp = (SampleObjectRec*)ArrayGetElement(ListOfSelections,0);
  729.                         /* open the temporary file */
  730.                         TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  731.                             CODE4BYTES('\?','\?','\?','\?'));
  732.                         if (TempFileLocation != NIL)
  733.                             {
  734.                                 FileType*                            FileDescriptor;
  735.  
  736.                                 if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  737.                                     {
  738.                                         BufferedOutputRec*        BufferedFile;
  739.  
  740.                                         BufferedFile = NewBufferedOutput(FileDescriptor);
  741.                                         if (BufferedFile != NIL)
  742.                                             {
  743.                                                 MyBoolean                            WriteSucceeded = False;
  744.  
  745.                                                 if (WriteBufferedOutput(BufferedFile,sizeof(MAGICSCRAPSTRING),
  746.                                                     MAGICSCRAPSTRING))
  747.                                                     {
  748.                                                         if (SampleObjectWriteOutData(SampleTemp,BufferedFile)
  749.                                                             == eFileLoadNoError)
  750.                                                             {
  751.                                                                 WriteSucceeded = True;
  752.                                                             }
  753.                                                     }
  754.                                                 if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  755.                                                     {
  756.                                                         char*                            Buffer;
  757.                                                         long                            NumberOfBytes;
  758.  
  759.                                                         NumberOfBytes = GetFileLength(FileDescriptor);
  760.                                                         Buffer = AllocPtrCanFail(NumberOfBytes,
  761.                                                             "SampleListCopyObject:  scrap buffer");
  762.                                                         if (Buffer != NIL)
  763.                                                             {
  764.                                                                 if (SetFilePosition(FileDescriptor,0))
  765.                                                                     {
  766.                                                                         if (0 == ReadFromFile(FileDescriptor,
  767.                                                                             Buffer,NumberOfBytes))
  768.                                                                             {
  769.                                                                                 if (SetScrapToThis(Buffer))
  770.                                                                                     {
  771.                                                                                         TotalSuccessFlag = True;
  772.                                                                                     }
  773.                                                                             }
  774.                                                                     }
  775.                                                                 ReleasePtr(Buffer);
  776.                                                             }
  777.                                                     }
  778.                                             }
  779.                                         CloseFile(FileDescriptor);
  780.                                     }
  781.                                 DeleteFile(TempFileLocation);
  782.                                 DisposeFileSpec(TempFileLocation);
  783.                             }
  784.                     }
  785.                 DisposeArray(ListOfSelections);
  786.             }
  787.         return TotalSuccessFlag;
  788.     }
  789.  
  790.  
  791. /* try to paste the clipboard in as a sample object.  returns False if it failed */
  792. /* or the clipboard did not contain a sample object. */
  793. MyBoolean                        SampleListPasteObject(SampleListRec* SampleList)
  794.     {
  795.         MyBoolean                    TotalSuccessFlag = False;
  796.         char*                            Scrap;
  797.  
  798.         CheckPtrExistence(SampleList);
  799.         Scrap = GetCopyOfScrap();
  800.         if (Scrap != NIL)
  801.             {
  802.                 FileSpec*                    TempFileLocation;
  803.  
  804.                 TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  805.                     CODE4BYTES('\?','\?','\?','\?'));
  806.                 if (TempFileLocation != NIL)
  807.                     {
  808.                         FileType*                            FileDescriptor;
  809.  
  810.                         if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  811.                             {
  812.                                 BufferedOutputRec*        BufferedFile;
  813.  
  814.                                 BufferedFile = NewBufferedOutput(FileDescriptor);
  815.                                 if (BufferedFile != NIL)
  816.                                     {
  817.                                         MyBoolean                            WriteSucceeded = False;
  818.  
  819.                                         if (WriteBufferedOutput(BufferedFile,PtrSize(Scrap),Scrap))
  820.                                             {
  821.                                                 WriteSucceeded = True;
  822.                                             }
  823.                                         if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  824.                                             {
  825.                                                 TotalSuccessFlag = SampleListPasteFromFile(SampleList,
  826.                                                     FileDescriptor);
  827.                                             }
  828.                                     }
  829.                                 CloseFile(FileDescriptor);
  830.                             }
  831.                         DeleteFile(TempFileLocation);
  832.                         DisposeFileSpec(TempFileLocation);
  833.                     }
  834.                 ReleasePtr(Scrap);
  835.             }
  836.         return TotalSuccessFlag;
  837.     }
  838.  
  839.  
  840. /* paste a sample object in from the file */
  841. MyBoolean                        SampleListPasteFromFile(SampleListRec* SampleList,
  842.                                             struct FileType* File)
  843.     {
  844.         MyBoolean                    TotalSuccessFlag = False;
  845.  
  846.         CheckPtrExistence(SampleList);
  847.         if (SetFilePosition(File,0))
  848.             {
  849.                 BufferedInputRec*    InputFile;
  850.  
  851.                 InputFile = NewBufferedInput(File);
  852.                 if (InputFile != NIL)
  853.                     {
  854.                         char                            HeaderTest[sizeof(MAGICSCRAPSTRING)];
  855.  
  856.                         if (ReadBufferedInput(InputFile,sizeof(MAGICSCRAPSTRING),HeaderTest))
  857.                             {
  858.                                 if (MemEqu(MAGICSCRAPSTRING,HeaderTest,sizeof(MAGICSCRAPSTRING)))
  859.                                     {
  860.                                         SampleObjectRec*            SampleTemp EXECUTE(= (SampleObjectRec*)0x81818181);
  861.  
  862.                                         if (eFileLoadNoError == SampleObjectNewFromFile(&SampleTemp,InputFile,
  863.                                             SampleList->CodeCenter,SampleList->MainWindow,SampleList))
  864.                                             {
  865.                                                 CheckPtrExistence(SampleTemp);
  866.                                                 /* add it to the scrolling object list */
  867.                                                 if (!InsertStringListElement(SampleList->List,NIL,NIL,SampleTemp,True))
  868.                                                     {
  869.                                                      FailurePoint:
  870.                                                         DisposeSampleObject(SampleTemp);
  871.                                                     }
  872.                                                  else
  873.                                                     {
  874.                                                         MainWindowDeselectAllOtherStringLists(SampleList->MainWindow,SampleList);
  875.                                                         SelectStringListElement(SampleList->List,SampleTemp);
  876.                                                         MakeStringListSelectionVisible(SampleList->List);
  877.                                                         /* add it to the array */
  878.                                                         if (!ArrayAppendElement(SampleList->SampleArray,SampleTemp))
  879.                                                             {
  880.                                                                 RemoveStringListElement(SampleList->List,SampleTemp,True);
  881.                                                                 goto FailurePoint;
  882.                                                             }
  883.                                                          else
  884.                                                             {
  885.                                                                 /* change the name in the list */
  886.                                                                 SampleListSampleNameChanged(SampleList,SampleTemp);
  887.                                                                 TotalSuccessFlag = True;
  888.                                                                 SampleList->SampleListChanged = True;
  889.                                                             }
  890.                                                     }
  891.                                             }
  892.                                     }
  893.                             }
  894.                         EndBufferedInput(InputFile);
  895.                     }
  896.             }
  897.         return TotalSuccessFlag;
  898.     }
  899.  
  900.  
  901. /* find out how many samples there are in this list */
  902. long                                SampleListHowMany(SampleListRec* SampleList)
  903.     {
  904.         CheckPtrExistence(SampleList);
  905.         return ArrayGetLength(SampleList->SampleArray);
  906.     }
  907.  
  908.  
  909. /* get an indexed sample from the list */
  910. struct SampleObjectRec*    SampleListGetIndexedSample(SampleListRec* SampleList, long Index)
  911.     {
  912.         SampleObjectRec*    Sample;
  913.  
  914.         CheckPtrExistence(SampleList);
  915.         ERROR((Index < 0) || (Index >= SampleListHowMany(SampleList)),PRERR(ForceAbort,
  916.             "SampleListGetIndexedSample:  index out of range"));
  917.         Sample = (SampleObjectRec*)ArrayGetElement(SampleList->SampleArray,Index);
  918.         CheckPtrExistence(Sample);
  919.         return Sample;
  920.     }
  921.